```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring MVC注解详解：@ModelAttribute与@SessionAttributes</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .article-title {
            font-family: 'Noto Serif SC', serif;
        }
        .code-block {
            background: #282c34;
            border-left: 4px solid #6e8efb;
        }
        .feature-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .footer-link:hover {
            color: #a777e3;
        }
        .drop-cap:first-letter {
            float: left;
            font-size: 3.5em;
            line-height: 0.9;
            margin: 0.1em 0.1em 0 0;
            color: #6e8efb;
            font-family: 'Noto Serif SC', serif;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:py-28">
        <div class="container mx-auto max-w-5xl text-center">
            <h1 class="article-title text-4xl md:text-5xl font-bold mb-6">Spring MVC注解深度解析</h1>
            <p class="text-xl md:text-2xl font-light mb-8 max-w-3xl mx-auto">@ModelAttribute 与 @SessionAttributes 的核心差异与应用场景</p>
            <div class="flex justify-center space-x-4">
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm font-medium">Spring MVC</span>
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm font-medium">注解详解</span>
                <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full text-sm font-medium">Web开发</span>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-4 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <p class="drop-cap text-gray-700 text-lg leading-relaxed">
                在Spring MVC框架中，<code class="bg-gray-100 px-2 py-1 rounded text-pink-600">@ModelAttribute</code>和<code class="bg-gray-100 px-2 py-1 rounded text-pink-600">@SessionAttributes</code>都是处理请求参数和管理模型数据的重要注解，但它们的作用范围和适用场景有着本质区别。本文将深入分析这两个注解的工作原理、典型用法以及最佳实践。
            </p>
        </section>

        <!-- Comparison Chart -->
        <section class="mb-16">
            <h2 class="article-title text-2xl font-bold mb-8 text-gray-800 border-b pb-2 flex items-center">
                <i class="fas fa-chart-bar text-blue-500 mr-2"></i>核心差异对比
            </h2>
            <div class="mermaid">
                graph TD
                    A[@ModelAttribute] --> B[请求级别]
                    A --> C[参数绑定]
                    A --> D[模型初始化]
                    E[@SessionAttributes] --> F[会话级别]
                    E --> G[数据共享]
                    E --> H[状态保持]
                    B -->|每次请求重新绑定| I[局部有效]
                    F -->|跨多个请求| J[全局有效]
                    C --> K[表单处理]
                    G --> L[用户会话]
            </div>
        </section>

        <!-- @ModelAttribute Section -->
        <section class="mb-16">
            <div class="flex items-center mb-6">
                <div class="bg-blue-100 p-3 rounded-full mr-4">
                    <i class="fas fa-code text-blue-600 text-xl"></i>
                </div>
                <h2 class="article-title text-2xl font-bold text-gray-800">1. @ModelAttribute 注解</h2>
            </div>

            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8">
                <div class="p-6">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-bullseye text-blue-500 mr-2"></i>核心作用
                    </h3>
                    <ul class="space-y-3 pl-5">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span><strong>请求参数绑定</strong>：将HTTP请求参数自动绑定到方法参数或模型属性中</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span><strong>模型初始化</strong>：在每个请求处理方法调用前执行，用于准备模型数据</span>
                        </li>
                    </ul>
                </div>
            </div>

            <div class="grid md:grid-cols-2 gap-8 mb-8">
                <div class="feature-card bg-white rounded-xl shadow-md p-6 transition-all duration-300">
                    <h3 class="text-lg font-semibold mb-3 text-gray-800 flex items-center">
                        <i class="fas fa-terminal text-blue-500 mr-2"></i>方法参数上的使用
                    </h3>
                    <div class="code-block text-gray-200 p-4 rounded-lg text-sm overflow-x-auto">
                        <pre><code>@GetMapping("/form")
public String showForm(
    @ModelAttribute("user") User user) {
    return "form";
}

@PostMapping("/submit")
public String submitForm(
    @ModelAttribute("user") User user) {
    // user对象已绑定表单数据
    return "result";
}</code></pre>
                    </div>
                    <p class="mt-3 text-gray-600 text-sm">
                        从请求参数自动创建User对象并绑定数据，或从模型中获取已存在的user属性
                    </p>
                </div>

                <div class="feature-card bg-white rounded-xl shadow-md p-6 transition-all duration-300">
                    <h3 class="text-lg font-semibold mb-3 text-gray-800 flex items-center">
                        <i class="fas fa-code-branch text-blue-500 mr-2"></i>方法上的使用
                    </h3>
                    <div class="code-block text-gray-200 p-4 rounded-lg text-sm overflow-x-auto">
                        <pre><code>@ModelAttribute("commonData")
public String populateCommonData() {
    return "公共数据";
}

@GetMapping("/page")
public String showPage() {
    // "commonData"已添加到模型
    return "page";
}</code></pre>
                    </div>
                    <p class="mt-3 text-gray-600 text-sm">
                        该方法会在控制器每个请求处理方法前执行，为模型添加公共数据
                    </p>
                </div>
            </div>

            <div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 rounded-r-lg mb-8">
                <div class="flex">
                    <div class="flex-shrink-0">
                        <i class="fas fa-lightbulb text-yellow-500"></i>
                    </div>
                    <div class="ml-3">
                        <h3 class="text-sm font-medium text-yellow-800">最佳实践</h3>
                        <div class="mt-2 text-sm text-yellow-700">
                            <p>• 使用@ModelAttribute处理表单提交时的数据绑定</p>
                            <p>• 为控制器添加公共模型数据时使用@ModelAttribute方法</p>
                            <p>• 避免在@ModelAttribute方法中执行耗时操作，会影响所有请求处理</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- @SessionAttributes Section -->
        <section class="mb-16">
            <div class="flex items-center mb-6">
                <div class="bg-purple-100 p-3 rounded-full mr-4">
                    <i class="fas fa-user-clock text-purple-600 text-xl"></i>
                </div>
                <h2 class="article-title text-2xl font-bold text-gray-800">2. @SessionAttributes 注解</h2>
            </div>

            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8">
                <div class="p-6">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
                        <i class="fas fa-bullseye text-purple-500 mr-2"></i>核心作用
                    </h3>
                    <ul class="space-y-3 pl-5">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>会话级数据存储</strong>：将模型属性存储在HTTP会话中</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-purple-500 mt-1 mr-2"></i>
                            <span><strong>跨请求数据共享</strong>：使数据在同一会话的多个请求间保持</span>
                        </li>
                    </ul>
                </div>
            </div>

            <div class="feature-card bg-white rounded-xl shadow-md p-6 mb-8 transition-all duration-300">
                <h3 class="text-lg font-semibold mb-3 text-gray-800 flex items-center">
                    <i class="fas fa-laptop-code text-purple-500 mr-2"></i>典型实现
                </h3>
                <div class="code-block text-gray-200 p-4 rounded-lg text-sm overflow-x-auto">
                    <pre><code>@Controller
@SessionAttributes("user")
public class UserController {

    @GetMapping("/form")
    public String showForm(Model model) {
        model.addAttribute("user", new User());
        return "form";
    }

    @PostMapping("/submit")
    public String submitForm(
        @ModelAttribute("user") User user) {
        // user对象会保存在会话中
        return "redirect:/next-step";
    }

    @GetMapping("/next-step")
    public String nextStep(
        @ModelAttribute("user") User user) {
        // 可以从会话中获取user对象
        return "view";
    }
}</code></pre>
                </div>
                <p class="mt-3 text-gray-600">
                    该示例展示了如何在整个用户会话期间保持user对象的状态，实现多步骤表单处理
                </p>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-blue-50 p-6 rounded-xl">
                    <h3 class="font-semibold mb-3 text-blue-800 flex items-center">
                        <i class="fas fa-thumbs-up text-blue-500 mr-2"></i>适用场景
                    </h3>
                    <ul class="space-y-2 pl-5">
                        <li class="flex items-start">
                            <i class="fas fa-check text-blue-400 mt-1 mr-2 text-xs"></i>
                            <span>多步骤表单处理流程</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-blue-400 mt-1 mr-2 text-xs"></i>
                            <span>购物车功能实现</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check text-blue-400 mt-1 mr-2 text-xs"></i>
                            <span>用户会话状态管理</span>
                        </li>
                    </ul>
                </div>

                <div class="bg-red-50 p-6 rounded-xl">
                    <h3 class="font-semibold mb-3 text-red-800 flex items-center">
                        <i class="fas fa-exclamation-triangle text-red-500 mr-2"></i>注意事项
                    </h3>
                    <ul class="space-y-2 pl-5">
                        <li class="flex items-start">
                            <i class="fas fa-times text-red-400 mt-1 mr-2 text-xs"></i>
                            <span>不要存储大量数据，会增加服务器内存压力</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-times text-red-400 mt-1 mr-2 text-xs"></i>
                            <span>注意会话超时处理</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-times text-red-400 mt-1 mr-2 text-xs"></i>
                            <span>集群环境下需要会话共享解决方案</span>
                        </li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- Summary Section -->
        <section class="mb-16">
            <h2 class="article-title text-2xl font-bold mb-8 text-gray-800 border-b pb-2">3. 关键区别总结</h2>
            <div class="overflow-x-auto">
                <table class="min-w-full divide-y divide-gray-200">
                    <thead class="bg-gray-50">
                        <tr>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">对比维度</th>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">@ModelAttribute</th>
                            <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">@SessionAttributes</th>
                        </tr>
                    </thead>
                    <tbody class="bg-white divide-y divide-gray-200">
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">作用范围</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">请求级别</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">会话级别</td>
                        </tr>
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">数据存储</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">模型对象中</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">HTTP会话中</td>
                        </tr>
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">生命周期</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">单次请求</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">整个会话期间</td>
                        </tr>
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">典型用途</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">表单数据绑定、模型初始化</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">跨请求数据共享、多步骤流程</td>
                        </tr>
                        <tr>
                            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">性能影响</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">较低</td>
                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">需注意会话大小</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <div class="mt-8 bg-indigo-50 p-6 rounded-xl">
                <h3 class="text-lg font-semibold mb-4 text-indigo-800 flex items-center">
                    <i class="fas fa-clipboard-check text-indigo-500 mr-2"></i>选择指南
                </h3>
                <div class="grid md:grid-cols-2 gap-6">
                    <div>
                        <h4 class="font-medium text-indigo-700 mb-2">使用 @ModelAttribute 当：</h4>
                        <ul class="space-y-2 text-sm">
                            <li class="flex items-start">
                                <i class="fas fa-angle-right text-indigo-400 mt-1 mr-2"></i>
                                <span>只需要处理单次请求的数据绑定</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-angle-right text-indigo-400 mt-1 mr-2"></i>
                                <span>需要为视图准备临时数据</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-angle-right text-indigo-400 mt-1 mr-2"></i>
                                <span>处理表单提交但不需要跨请求保持状态</span>
                            </li>
                        </ul>
                    </div>
                    <div>
                        <h4 class="font-medium text-indigo-700 mb-2">使用 @SessionAttributes 当：</h4>
                        <ul class="space-y-2 text-sm">
                            <li class="flex items-start">
                                <i class="fas fa-angle-right text-indigo-400 mt-1 mr-2"></i>
                                <span>需要在多个请求间保持数据状态</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-angle-right text-indigo-400 mt-1 mr-2"></i>
                                <span>实现多步骤表单或向导式界面</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-angle-right text-indigo-400 mt-1 mr-2"></i>
                                <span>需要保存用户会话特定的少量数据</span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-8">
        <div class="container mx-auto px-4 text-center">
            <div class="flex flex-col items-center">
                <div class="mb-4">
                    <span class="text-lg font-medium">技术小馆</span>
                </div>
                <div>
                    <a href="http://www.yuque.com/jtostring" class="footer-link text-sm hover:text-purple-300 transition-colors duration-200">http://www.yuque.com/jtostring</a>
                </div>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            fontFamily: '"Noto Sans SC", sans-serif'
        });
    </script>
</body>
</html>
```